JSGF.Stage = JSGF.inherit(JSGF.Object);

JSGF.Stage.prototype.init = function(controller) {
	this.type = "JSGF.Stage";
	this.__basetime__ = 0;
	this.__basecount__ = 0;
	this.__fps__ = 0;
	this.__draw__ = true;

	if (!controller) {
		return null;
	}
	this.__listSprite__ = new Array();
	this.__backgroundImage__ = null;
	this.__tid__ = null;
	this.__interval__ = 0;
	this.__backupOnkeydown__ = window.onkeydown;
	this.__backupOnkeyup__ = window.onkeyup;
	this.controller = controller;
	this.canvas = this.controller.canvas;
	this.context = this.controller.context;
	this.enableMouseEvent = true;
	this.clear();
	this.onLoad();
	this.draw();
	var self = this;
	window.onkeydown = function(e) {
		self.onKeyDown(e);
	};
	window.onkeyup = function(e) {
		self.onKeyUp(e);
	};
	this.canvas.onclick = function(e) {
		var rect = e.target.getBoundingClientRect();
		var x = e.clientX - rect.left;
		var y = e.clientY - rect.top;
		if (self.enableMouseEvent == true) {
			for (var i = 0; i < self.__listSprite__.length; i++) {
				var sprite = self.__listSprite__[i];
				if (sprite != null && sprite.visible == true) {
					if (sprite.within(x, y)) {
						sprite.onClick(sprite, x - sprite.x, y - sprite.y);
					}
				}
			}
		}
		self.onClick(x, y);
	}
	this.canvas.ondblclick = function(e) {
		var rect = e.target.getBoundingClientRect();
		var x = e.clientX - rect.left;
		var y = e.clientY - rect.top;
		if (self.enableMouseEvent == true) {
			for (var i = 0; i < self.__listSprite__.length; i++) {
				var sprite = self.__listSprite__[i];
				if (sprite != null && sprite.visible == true) {
					if (sprite.within(x, y)) {
						sprite.onDblClick(sprite, x - sprite.x, y - sprite.y);
					}
				}
			}
		}
		self.onDblClick(x, y);
	}
	this.canvas.onmousemove = function(e) {
		var rect = e.target.getBoundingClientRect();
		var x = e.clientX - rect.left;
		var y = e.clientY - rect.top;
		if (self.enableMouseEvent == true) {
			for (var i = 0; i < self.__listSprite__.length; i++) {
				var sprite = self.__listSprite__[i];
				if (sprite != null && sprite.visible == true) {
					if (sprite.within(x, y)) {
						sprite.onMouseMove(sprite, x - sprite.x, y - sprite.y);
					}
				}
			}
		}
		self.onMouseMove(x, y);
	}
	this.canvas.onmousedown = function(e) {
		var rect = e.target.getBoundingClientRect();
		var x = e.clientX - rect.left;
		var y = e.clientY - rect.top;
		if (self.enableMouseEvent == true) {
			for (var i = 0; i < self.__listSprite__.length; i++) {
				var sprite = self.__listSprite__[i];
				if (sprite != null && sprite.visible == true) {
					if (sprite.within(x, y)) {
						sprite.onMouseDown(sprite, x - sprite.x, y - sprite.y);
					}
				}
			}
		}
		self.onMouseDown(x, y);
	}
	this.canvas.onmouseup = function(e) {
		var rect = e.target.getBoundingClientRect();
		var x = e.clientX - rect.left;
		var y = e.clientY - rect.top;
		if (self.enableMouseEvent == true) {
			for (var i = 0; i < self.__listSprite__.length; i++) {
				var sprite = self.__listSprite__[i];
				if (sprite != null && sprite.visible == true) {
					if (sprite.within(x, y)) {
						sprite.onMouseUp(sprite, x - sprite.x, y - sprite.y);
					}
				}
			}
		}
		self.onMouseUp(x, y);
	}
}

JSGF.Stage.prototype.release = function() {
	this.stopAnimation();
	this.clear();
	this.__listSprite__ = new Array();
	window.onkeydown = this.__backupOnkeydown__;
	window.onkeyup = this.__backupOnkeyup__;
	this.onUnload();
}

JSGF.Stage.prototype.draw = function() {
	this.clear();
	var dt = 0;
	var unixtime = (new Date).getTime();
	if (this.__basetime__ != 0) {
		this.__basecount__++;
		dt = Math.floor((unixtime - this.__basetime__) / this.__basecount__);
		var f = "" + (Math.round(10000 / dt) / 10);
		var farray = f.split(".");
		if (farray.length == 1) {
			farray.push("0");
		}
		this.__fps__ = farray.join(".");
		if (this.__basecount__ > 10000) {
			this.__basetime__ = unixtime;
			this.__basecount__ = 0;
		}
	} else {
		this.__basetime__ = unixtime;
		this.__basecount__ = 0;
	}
	if (self.tid != null) {
		clearTimeout(self.__tid__);
	}
	this.onDraw(dt);
	this.__listSprite__.sort(function func(a,b){
		if (a == null || b == null) {
			return 0;
		}
		if (a.zIndex > b.zIndex) {
			return 1;
		}
		if (a.zIndex < b.zIndex) {
			return -1;
		}
		return 0;
	});
	if (this.__backgroundImage__ != null && this.__backgroundImage__.visible == true) {
		var bg = this.__backgroundImage__;
		if (bg.type == "JSGF.BackgroundImage") {
			if (bg.width == null || bg.height == null) {
				return;
			}
			var bgposx = bg.x;
			var bgposy = bg.y;
			if (bg.x < 0) {
				bgposx = bg.width - (-bg.x);
			}
			if (bg.y < 0) {
				bgposy = bg.height - (-bg.y);
			}
			if (bg.getImage() != null) {
				this.context.drawImage(bg.getImage(), -bgposx, -bgposy, bg.width, bg.height);
			}
			if (bg.repeat == true) {
				var timesX = Math.ceil((this.getWidth() + bgposx) / bg.width);
				var timesY = Math.ceil((this.getHeight() + bgposy) / bg.height);
				for (y = 0; y < timesY; y++) {
					for (x = 0; x < timesX; x++) {
						var tmpposx = (x * bg.width) - bgposx;
						var tmpposy = (y * bg.height) - bgposy;
						this.context.drawImage(bg.getImage(), tmpposx, tmpposy, bg.width, bg.height);
					}
				}
			}
		}
	}
	for (var i = 0; i < this.__listSprite__.length; i++) {
		var sprite = this.__listSprite__[i];
		if (sprite != null && sprite.visible == true) {
			sprite.draw(this.context);
		}
	}
}

JSGF.Stage.prototype.animationCallback = function(self) {
	if (this.__draw__  == true) {
		this.__draw__ = false;
		self.draw();
		this.__draw__ = true;
	}
}

////////////////////////////////////////
//Public
////////////////////////////////////////

JSGF.Stage.prototype.getController = function() {
	return this.controller;
}

JSGF.Stage.prototype.setWidth = function(width) {
	this.canvas.width = width;
}

JSGF.Stage.prototype.setHeight = function(height) {
	this.canvas.height = height;
}

JSGF.Stage.prototype.getWidth = function() {
	return this.canvas.width;
}

JSGF.Stage.prototype.getHeight = function() {
	return this.canvas.height;
}

JSGF.Stage.prototype.clear = function() {
	this.context.clearRect( 0, 0, this.canvas.width, this.canvas.height );
}

JSGF.Stage.prototype.setEnableSpriteMouseEvent = function(enable) {
	if (enable == true || enable == false) {
		this.enableMouseEvent = enable;
	}
}

JSGF.Stage.prototype.getEnableSpriteMouseEvent = function() {
	return this.enableMouseEvent;
}

JSGF.Stage.prototype.drawUpdate = function() {
	this.draw();
}

JSGF.Stage.prototype.startAnimation = function(interval) {
	var self = this;
	this.__basetime__ = 0;
	this.__basecount__ = 0;
	if (this.__tid__ != null) {
		clearInterval(this.__tid__);
		this.__tid__ = null;
	}
	this.__interval__ = interval;
	this.__tid__ = setInterval(function() {
		self.animationCallback(self);
	}, interval);
}

JSGF.Stage.prototype.stopAnimation = function() {
	if (this.__tid__ != null) {
		clearInterval(this.__tid__);
	}
	this.__tid__ = null;
	this.__interval__ = 0;
}

JSGF.Stage.prototype.appendSprite = function(sprite) {
	if (sprite == null) {
		return false;
	}
	if (!sprite.__check__ || sprite.__check__ != "JSGF.Sprite") {
		return false;
	}
	this.__listSprite__.push(sprite);
}

JSGF.Stage.prototype.removeSprite = function(sprite) {
	for (var i = 0; i < this.__listSprite__.length; i++) {
		if (this.__listSprite__[i] == sprite) {
			this.__listSprite__[i] = null;
		}
	}
}

JSGF.Stage.prototype.appendBackgroundImage = function(backgroundimage) {
	if (backgroundimage == null) {
		return false;
	}
	if (!backgroundimage.type || (backgroundimage.type != "JSGF.BackgroundImage")) {
		return false;
	}
	this.__backgroundImage__ = backgroundimage;
}

JSGF.Stage.prototype.removeBackgroundImage = function(backgroundimage) {
	this.__backgroundImage__ = null;
}

JSGF.Stage.prototype.getFps = function() {
	return this.__fps__;
}

////////////////////////////////////////
// definition by user
////////////////////////////////////////

JSGF.Stage.prototype.onLoad = function() {

}

JSGF.Stage.prototype.onUnload = function() {

}

JSGF.Stage.prototype.onDraw = function(dt) {

}

JSGF.Stage.prototype.onKeyDown = function(e) {

}

JSGF.Stage.prototype.onKeyUp = function(e) {

}

JSGF.Stage.prototype.onClick = function(x, y) {

}

JSGF.Stage.prototype.onDblClick = function(x, y) {

}

JSGF.Stage.prototype.onMouseMove = function(x, y) {

}

JSGF.Stage.prototype.onMouseDown = function(x, y) {

}

JSGF.Stage.prototype.onMouseUp = function(x, y) {

}

